<template>
  <div class="container">
    <div class="app-container">
      <el-button style="margin: 0 0 10px 0;" type="primary" size="small" @click="visible = true">添加角色</el-button>
      <el-table v-loading="loading" :header-cell-style="{background: '#f5f6f8'}" border :data="tableData" style="width: 100%">
        <el-table-column label="序号" width="80">
          <template #default="{ $index }">
            {{ $index + 1 + pagesize * (page - 1) }}
          </template>
        </el-table-column>
        <el-table-column prop="name" label="角色" width="200">
          <template #default="{row}">
            <el-input v-if="row.isEdit" v-model="row.editRow.name" size="medium" />
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="state" label="启用" width="200">
          <template #default="{row}">
            <el-switch v-if="row.isEdit" v-model="row.editRow.state" :active-value="1" :inactive-value="0" />
            <span v-else>{{ row.state === 1 ? '已启用' : '未启用' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述" width="600">
          <template #default="{row}">
            <el-input v-if="row.isEdit" v-model="row.editRow.description" size="medium" type="textarea" />
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="{row}">
            <template v-if="row.isEdit">
              <el-button size="mini" type="primary" @click="updateRole(row)">确定</el-button>
              <el-button size="mini" @click="deselect(row)">取消</el-button>
            </template>
            <template v-else>
              <el-button type="text" @click="onPerm(row.id)">分配权限</el-button>
              <el-button type="text" @click="row.isEdit = true">编辑</el-button>
              <el-popconfirm
                title="确定删除吗？"
                @onConfirm="delRole(row.id)"
              >
                <el-button slot="reference" type="text">删除</el-button>
              </el-popconfirm>
            </template>
          </template>
        </el-table-column>
      </el-table>
      <el-row type="flex" justify="center">
        <el-pagination
          layout="prev, pager, next"
          :page-size="pagesize"
          :page="page"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </el-row>
    </div>
    <el-dialog :close-on-click-modal="false" :visible.sync="visible" title="新增角色" width="500px">
      <el-form ref="myFormRef" style="width:400px" :model="formData" :rules="rules" size="mini" label-width="120px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="formData.name" />
        </el-form-item>
        <el-form-item label="启用">
          <el-switch v-model="formData.state" :active-value="1" :inactive-value="0" />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="formData.description" type="textarea" rows="3" />
        </el-form-item>
        <el-form-item>
          <el-row type="flex" justify="center">
            <el-button type="primary" @click="onSubmit">确定</el-button>
            <el-button @click="validate = false">取消</el-button>
          </el-row>
        </el-form-item>
      </el-form>
    </el-dialog>

    <el-dialog :visible.sync="permVisible" title="分配权限">
      <el-tree ref="permRef" check-strictly show-checkbox node-key="id" :default-checked-keys="permIds" :data="permList" :props="{label:'name'}" default-expand-all :expand-on-click-node="false" />
      <template #footer>
        <el-row type="flex" justify="center">
          <el-button size="mini" type="primary" @click="onAssignPerm">确定</el-button>
          <el-button size="mini" @click="permVisible = false">取消</el-button>
        </el-row>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { addRoleAPI, delRoleAPI, getRoleDetailAPI, getRoleListAPI, updateAssignPermAPI, updateRoleAPI } from '@/api/role'
import { getPermissionAPI } from '@/api/permission'
import convertToTree from '@/utils/data-conversion'
export default {
  name: 'Role',
  data() {
    return {
      permIds: [], // 角色已有的权限id
      permVisible: false, //  分配权限弹出层
      permList: [], // 权限树
      isEdit: false, // 控制行内显示文本/input的变量
      visible: false, // 新增弹出层
      loading: true, // 加载状态
      tableData: [],
      pagesize: 5, // 每页数据
      page: 1, // 当前页
      total: 1, // 数据总数
      formData: {
        name: '',
        description: '',
        state: 0
      },
      rules: {
        name: [
          { required: true, message: '角色名称不能为空', trigger: 'blur' }
        ],
        description: [
          { required: true, message: '角色描述不能为空', trigger: 'blur' }
        ]
      }
    }
  },
  watch: {
    // 监听visible的变化 通过ref调用表单重置方法
    visible(newValue) {
      if (!newValue) {
        this.$refs.myFormRef.resetFields()
        // 手动把表单数据初始化
        this.formData = {
          name: '',
          description: '',
          state: 0
        }
      }
    }
  },
  created() {
    this.getRoleList()
  },
  methods: {
    async getRoleList() {
      this.loading = true // 请求前开启加载状态
      const result = await getRoleListAPI({ pagesize: this.pagesize, page: this.page })
      this.tableData = result.data.rows
      this.total = result.data.total
      this.loading = false // 请求后关闭加载状态
      // 数据回来后 通过遍历给每条数据
      this.tableData.forEach(item => {
        // item.isEdit = false 不是响应式的数据
        // 需要通过this.$set 让vue重新劫持数据
        this.$set(item, 'isEdit', this.isEdit)
        // 备份数据 实现表单双向绑定数据 点击取消还原
        this.$set(item, 'editRow', {
          name: item.name,
          description: item.description,
          state: item.state
        })
      })
    },
    // 分页器事件
    handleSizeChange(pagesize) {
      this.pagesize = pagesize
      this.getRoleList()
    },
    handleCurrentChange(page) {
      this.page = page
      this.getRoleList()
    },
    // 点击按钮获取表单示例
    async onSubmit() {
      await this.$refs.myFormRef.validate()
      // 验证通过发送添加请求
      await addRoleAPI(this.formData)
      this.$message.success('新增角色成功') // 提示用户
      this.getRoleList() // 获取最新数据
      this.visible = false // 关闭弹窗
    },
    // 修改角色
    async updateRole(row) {
      if (row.editRow.name && row.editRow.description) {
        await updateRoleAPI({ ...row.editRow, id: row.id })
        this.$message.success('修改角色成功') // 提示用户
        Object.assign(row, { // 更新数据 关闭行内编辑
          ...row.editRow,
          isEdit: false
        })
      } else {
        this.$message.info('名字或描述不能为空') // 提示用户
      }
      // this.getRoleList() // 获取最新数据
      // this.tableData[index].isEdit = false // 关闭弹窗
    },
    // 取消修改角色
    deselect(row) {
      row.isEdit = false // 关闭弹窗
      // 回复数据
      row.editRow = {
        name: row.name,
        description: row.description,
        state: row.state
      }
    },
    async delRole(id) {
      // 获取id 发送调用删除请求
      await delRoleAPI(id)
      this.$message.success('删除角色成功') // 提示用户
      // 当前页只有一条数据时 需要加载前一页的数据
      if (this.tableData.length === 1) this.page--
      this.getRoleList() // 获取最新数据
      this.visible = false // 关闭弹窗
    },
    // 点击分配权限
    async  onPerm(id) {
      const { data } = await getPermissionAPI() // 获取权限节点api
      this.permList = convertToTree(data) // 转成树形数据
      const result = await getRoleDetailAPI(id)
      this.permIds = result.data.permIds
      this.permVisible = true
      this.id = id // 直接把id 挂载vue实例对象上 不在data声明的不是响应式
    },
    // 点击分配权限确定按钮
    async  onAssignPerm() {
      const permIds = this.$refs.permRef.getCheckedKeys() // 树组件的方法 获取用户选中的值 是个数组
      await updateAssignPermAPI({ permIds, id: this.id }) // 调用更新分配权限api
      this.$message.success('分配成功')
      this.permVisible = false
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  padding: 10px;
  font-size: 14px;
}
</style>
